package com.lanchetech.merchant.config;


import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import com.lanchetech.entity.Merchant;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.apache.ibatis.mapping.MappedStatement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Configuration
public class MyBatisPlusConfig {

    @Autowired
    HttpServletRequest request;

    /**
     * 分页插件
     *
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 创建SQL解析器集合
        List<ISqlParser> sqlParserList = new ArrayList<>();

        // 创建租户SQL解析器
        TenantSqlParser tenantSqlParser = new TenantSqlParser();

        // 设置租户处理器
        tenantSqlParser.setTenantHandler(new TenantHandler() {
            @Override
            public Expression getTenantId(boolean where) {
                Merchant merchant = (Merchant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                return new LongValue(merchant.getTenantId());
            }

            @Override
            public String getTenantIdColumn() {
                // 对应数据库租户ID的列名
                return "tenant_id";
            }

            @Override
            public boolean doTableFilter(String tableName) {
                // 是否需要需要过滤某一张表
                List<String> tableNameList = Arrays.asList(
                        "WORKER_NODE",
                        "area",
                        "logistics_company",
                        "merchant_permission",
                        "merchant_role_permission",
                        "street",
                        "role",
                        "sms",
                        "category",
                        "category_brand",
                        "category_spec",
                        "brand",
                        "spec",
                        "unit",
                        "order_address",
                        "invoice_account",
                        "spu_attribute",
                        "attribute",
                        "recommend_spu",
                        "tenant",
                        "order_discount",
                        "comment_statistics",
                        "shop",
                        "user",
                        "shop_statistics",
                        "appointment_setting",
                        "custom_page_data",
                        "shop_amount",
                        "industry",
                        "`user`",
                        "withdraw",
                        "invoiceAccount",
                        "replace_image",
                        "shop_collection",
                        "spu_statistics",
                        "shop_collection",
                        "card_flow",
                        "user_commission",
                        "zone_spu",
                        "consumption_amount",
                        "hipo_config",
                        "performance_amount",
                        "consumption_record",
                        "invite_first_buy",
                        "order_comment",
                        "give_member_record",
                        "`identity`",
                        "groups_performance",
                        "shareholder_performance",
                        "card_consumption_fund",
                        "dividend_precipitation",
                        "share_activity_spu",
                        "share_detailed",
                        "activity_bind_spu",
                        "user_address",
                        "lottery"
                );
                if (tableNameList.contains(tableName)) {
                    return true;
                }
                return false;
            }
        });

        sqlParserList.add(tenantSqlParser);
        paginationInterceptor.setSqlParserList(sqlParserList);
        paginationInterceptor.setSqlParserFilter(metaObject -> {
            MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
            // 过滤自定义查询此时无租户信息约束【 麻花藤 】出现
            List<String> tableNameList = Arrays.asList(
                    "com.lanchetech.dao.MerchantMapper.findOneByUsername",
                    "com.lanchetech.dao.MerchantRoleMapper.insertAdminRole",
                    "com.lanchetech.dao.MerchantMapper.insertAdmin",
                    "com.lanchetech.dao.MerchantMapper.getOneByUsername",
                    "com.lanchetech.dao.MerchantMapper.register",
                    "com.lanchetech.dao.MsgUserMapper.findAllByRoleAndStatusAndDeleted",
                    "com.lanchetech.dao.MsgMapper.findOneLastByTenantIdAndFromId",
                    "com.lanchetech.dao.FreezeAmountMapper.insert",
                    "com.lanchetech.dao.TenantFlowMapper.insert",
                    "com.lanchetech.dao.SpuCommissionMapper.insert",
                    "com.lanchetech.dao.SpuMapper.insert",
                    "com.lanchetech.dao.SpuMapper.findAllByIds",
                    "com.lanchetech.dao.CouponMapper.findAllByIds",
                    "com.lanchetech.dao.CustomPageMapper.selectByPrimaryKey",
                    "com.lanchetech.dao.CustomPageMapper.findAllPage",
                    "com.lanchetech.dao.CustomPageMapper.findAllPage_COUNT",
                    "com.lanchetech.dao.CustomPageDataMapper.findAllByCustomPageId",
                    "com.lanchetech.dao.SpuStatisticsMapper.getSpuClickTrend",
                    "com.lanchetech.dao.SpuStatisticsMapper.getSpuVisitorTrend",
                    "com.lanchetech.dao.AfterSaleMapper.getSpuRefundTrend",
                    "com.lanchetech.dao.OrderSkuMapper.getSpuCompleteTrend",
                    "com.lanchetech.dao.OrderSkuMapper.getSpuCustomerTrend",
                    "com.lanchetech.dao.ShareActivitySpuMapper.getBySkuIds",
                    "com.lanchetech.dao.OrderSkuMapper.getSpuCustomerTrend",
                    "com.lanchetech.dao.ActivityBindSpuMapper.getList"
            );
            if (tableNameList.contains(ms.getId())) {
                return true;
            }
            return false;
        });
        // 设置请求的页面大于最大页后操作， true调回到首页，false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量，默认 500 条，-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));

        return paginationInterceptor;
    }

}
